<template>
	<div class="app">
		<div class="left">
			<div class="container" ref="container"></div>
		</div>
		<div class="right">
			<div class="title">形状：</div>
			<select v-model="shape">
				<option v-for="item in shapeOptions" :key="item.value" :value="item.value">
					{{ item.label }}
				</option>
			</select>
			<div class="title">颜色：</div>
			<div>
				<div v-for="item in theme" :key="item.name">
					<div>{{ item.name }}<input v-model="themeValue" type="radio" :value="item.value"></div>
					<div class="theme-box">
						<div v-for="color in item.color" :key="color" :style="{backgroundColor:color}" class="theme__block"></div>
					</div>
				</div>
			</div>
			<div class="title">排列方式：</div>
			<select v-model="sortValue">
				<option v-for="item in sortOptions" :key="item.value" :value="item.value">
					{{ item.label }}
				</option>
			</select>
			<div>字号范围：</div>
			<div class="font">
				<input v-model="fontRange.min" type="number" />
				-
				<input v-model="fontRange.max" />
			</div>
			<div class="title">字体设置：</div>
			<select v-model="fontFamilyValue">
				<option v-for="item in fontFamilyOptions" :key="item.value" :value="item.value">
					{{ item.label }}
				</option>
			</select>
		</div>
	</div>
</template>

<script>
import * as echarts from 'echarts';
import 'echarts-wordcloud';
import data from './data';
import { addListener, removeListener } from 'resize-detector';
import debounce from 'lodash.debounce'
import shape from './shape';
import { getStringColor } from './utils'

/** @name 排列方式 **/
const SORT = {
  horizontal: {
    rotationRange: [0, 0],
    rotationStep: 0,
  },
  diagonal: {
    rotationRange: [-90, 90],
    rotationStep: 7,
  },
  blendHV: {
    rotationRange: [0, 90],
    rotationStep: 90,
  },
  blendHC: {
    rotationRange: [0, 90],
    rotationStep: 45,
  },
};

export default {
	data() {
		return {
			_chart: null,
			_options: {
				tooltip: {
					show: true,
				},
				series: [
					{
						type: 'wordCloud',
						width: '70%',
						height: '70%',
						left: 'center',
						top: 'center',
						right: null,
						bottom: null,
						/* 形状:
						* circle-圆形(默认)、cardioid-心形、diamond-菱形、triangle-forward-三角形向前、
						* triangle-三角形、pentagon-五边形、star-五角星
						*/
						shape: 'circle',
						// 词语间距
						gridSize: 0,
						// 字体大小范围
						sizeRange: [5, 18],
						// 文字旋转角度范围
						rotationRange: [-90, 90],
        		rotationStep: 45,
						// 是否渲染超出画布的文字
						drawOutOfBound: false,
						data: [],
						// 渲染时有动画效果
						layoutAnimation: true,
						// 自动收缩文本
						shrinkToFit: true,
						// 全局样式
						textStyle: {
						// 	// color: 'red',
						// 	color: function () {
						// 			// Random color
						// 			return 'rgb(' + [
						// 					Math.round(Math.random() * 160),
						// 					Math.round(Math.random() * 160),
						// 					Math.round(Math.random() * 160)
						// 			].join(',') + ')';
						// 	}
						},
						minRotation: 90,
					},
				],
			},
			shape: 'circle',
			theme: [
				{
					name: '姹紫嫣红',
					color: [
						'#02E1FD',
						'#7F96FD',
						'#02C0FF',
						'#FF0270',
						'#FFA621',
						'#FEE600',
						'#27F28E',
						'#96F62A',
						'#F98639',
						'#28D5D7',
						'#F4F452',
						'#768EFF',
					],
					value: '1',
				},
				{
					name: '馥郁芬芳',
					color: [
						'#07EDE9',
						'#FF7D6C',
						'#FFDD71',
						'#81FFC3',
						'#E3A3FC',
						'#F8FFA3',
						'#9286FE',
						'#9AEE8C',
						'#F4F452',
						'#02C0FD',
						'#B598FF',
						'#738CFF',
					],
					value: '2',
				},
				{
					name: '蔚蓝海岸',
					color: [
						'#94E5FA',
						'#69CCF0',
						'#9AF1E8',
						'#4AC5DE',
						'#5AA9FF',
						'#4EAFF4',
						'#5BE4C5',
						'#43BBD9',
						'#37CAFF',
						'#70E2FF',
						'#4096F3',
						'#719FFC',
					],
					value: '3',
				},
			],
			themeValue: '1',
			sortValue: 'horizontal',
			fontRange: {
				min: 12,
				max: 24,
			},
			fontFamilyValue: '微软雅黑'
		}
	},
	watch: {
		fontRange: {
			deep: true,
			handler() {
				this.setOptions();
			}
		},
		shape() {
			this.setOptions();
		},
		themeValue() {
			this.setOptions();
		},
		sortValue() {
			this.setOptions();
		},
		fontFamilyValue() {
			this.setOptions();
		}
	},
	computed: {
		shapeOptions() {
			return [
				{ label: '圆形', value: 'circle' },
				{ label: '椭圆', value: 'ellipse' },
				{ label: '五角星', value: 'star' },
				{ label: '菱形', value: 'diamond' },
				{ label: '三角形', value: 'triangleTop' },
				{ label: '正方形', value: 'square' },
				{ label: '长方形', value: 'rectangle' },
				{ label: '箭头', value: 'arrowRight' },
			];
		},
		sortOptions() {
			return [
			  { label: '横向', value: 'horizontal' },
			  { label: '对角线', value: 'diagonal' },
			  { label: '横竖混排', value: 'blendHV' },
			  { label: '横切混排', value: 'blendHC' },
			];
		},
		fontFamilyOptions() {
			return [
				'Arial',
				'Courier New',
				'Georgia',
				'Helvetica',
				'Impact',
				'times new roman',
				'Trebuchet ms',
				'Verdana',
				'仿宋',
				'华文仿宋',
				'华文宋体',
				'华文楷体',
				'宋体',
				'微软雅黑',
				'黑体',
				'楷体',
				'方正楷体',
				'方正黑体',
				'方正仿宋',
			].map(item => ({ label: item, value: item }))
		}
	},
	mounted() {
		this.initChart();

	},
	methods: {
		handleInput: debounce(function() {
			if (this._chart) {
				this._chart.resize();
			}
    }, 200),
		/** @name 初始化 **/
		initChart() {
			this.$nextTick(() => {
				if (this._chart) this._chart.dispose();
				if (this.$refs?.container) {
					this._chart = echarts.init(this.$refs.container);
				}
				if (!this._chart) return;
				addListener(this.$refs.container, this.handleInput);
				this._chart.clear();
				this.setOptions();
			});
		},
		setOptions() {
			if (!this._chart) return;
			const seriesItem = this._data._options.series[0];
			// 数据
			const theme = this.theme.find(item => item.value === this.themeValue);
			seriesItem.data = data.map(item => ({
				...item,
				textStyle: {
					color: getStringColor(item.name, theme.color)
				}
			}));
			// 排列方式
			const sortConfig = SORT[this.sortValue];
			if (sortConfig) {
				seriesItem.rotationRange = sortConfig.rotationRange;
				seriesItem.rotationStep = sortConfig.rotationStep;
			}
			// 字号范围
			seriesItem.sizeRange = [
				this.fontRange.min,
				this.fontRange.max,
			];
			// 字体设置
			const fontFamily = this.fontFamilyValue;
			if (fontFamily) {
				seriesItem.textStyle.fontFamily = fontFamily;
			}
			// 保持maskImage属性的图像横纵比例
			seriesItem.keepAspect = true;
			// 形状
			const shapeConfig = shape[this.shape];
			seriesItem.shape = shapeConfig.shape;
			const maskImage = new Image();
			maskImage.src = shapeConfig.img;
			maskImage.onload = () => {
				seriesItem.maskImage = maskImage;
				this._chart.clear();
				this._chart.setOption(this._data._options, { notMerge: true });
			};
		}
	}
}
</script>

<style>
body {
	padding: 0;
	margin: 0;
}
.app {
	width: 100vw;
	height: 100vh;
	padding: 20px;
	box-sizing: border-box;
	display: flex;
}
.left {
	flex: 1;
	overflow: hidden;
	box-sizing: border-box;
	padding: 10px;
}
.right {
	width: 300px;
	padding-left: 20px;
}
.container {
	width: 100%;
	/* width: 600px; */
	height: 400px;
	border: 1px solid #ccc;
}
.title {
	margin: 10px 0;
	font-weight: bold;
}
.font {
	display: flex;
}
.font > input {
	width: 100px;
}
.theme-box {
	display: flex;
}
.theme__block {
	width: 20px;
	height: 12px;
}
</style>
